package eg.edu.eelu.fyp2013.jdetector.core.filters.impl;

import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import eg.edu.eelu.fyp2013.jdetector.core.filters.SinglePixelFilter;

public class ContrastStretching implements SinglePixelFilter {


	public static class ColorRangeSegmentTransform{
		public int inputMin;
		public int inputMax;
		public int outMin;
		public int outMax;
	}

	/**an array of color transformations referring to every color component of the color.
	 * it contains only 1 element for gray scale image or three  elements for RGB images.<br>
	 * Every Element of this array is an ArrayList of Transformation segment per color component (channel), 
	 * that covers the color component Range [0-255]
	 */
	ArrayList<ColorRangeSegmentTransform> [] colorTransform;
	
	
	public static final int RED= 0;
	public static final int GREEN= 1;
	public static final int BLUE= 2;

	
	@SuppressWarnings("unchecked")
	public void setNumberOfComponentsPerColor(int noOfComponents){
		colorTransform= new ArrayList[noOfComponents];
		for (int i =0; i < noOfComponents ; i++){
			colorTransform[i]= new ArrayList<ContrastStretching.ColorRangeSegmentTransform>();
		}
	}
	
	public void setColorComponentSegments(int componentNumber, ArrayList<ColorRangeSegmentTransform>  segments){
		colorTransform[componentNumber]=segments;
		buildLookupTable(componentNumber);
	}
	void setColorComponentSegments(int componentNumber, ColorRangeSegmentTransform[] segments){
		for (ColorRangeSegmentTransform colorRangeSegmentTransform : segments) {
			colorTransform[componentNumber].add(colorRangeSegmentTransform);
		}
		buildLookupTable(componentNumber);
	}
	
	/**default constructor. initializes the color components to 3 (R, G, and B); and initializes
	 * the transform to an identical one
	 */
	public ContrastStretching() {
		this.setNumberOfComponentsPerColor(3);
		for (int i = 0; i < colorTransform.length; i++) {
			ColorRangeSegmentTransform segmentTransform = new ColorRangeSegmentTransform();
			segmentTransform.inputMin=0;
			segmentTransform.inputMax=255;
			segmentTransform.outMin=0;
			segmentTransform.outMax=255;
			ArrayList<ColorRangeSegmentTransform> segments = new ArrayList<ContrastStretching.ColorRangeSegmentTransform>();
			segments.add(segmentTransform);
			this.setColorComponentSegments(i, segments);
		}
	}
	
	private void buildLookupTable(int componentNumber) {
		// TODO Auto-generated method stub
		
	}

	/**
	 * @author Ahmed
	 */
	
	public int stretchColor (int existingColor, ColorRangeSegmentTransform segmrnt){
		float StretchedColor =0;
		
		return (int)StretchedColor;
	}
	
	/**
	 * @author Moshen
	 * @author Nafisa
	 */
	@Override
	public Image applyFilter(BufferedImage inImage) {
		BufferedImage outImage = new BufferedImage(inImage.getWidth(), inImage.getHeight(), BufferedImage.TYPE_INT_RGB/*inImage.getType()*/);
		
		int tempPixelColor;
		int red, green, blue;

		for (int i = 0; i < outImage.getHeight(); i++) {
			for (int j = 0; j < outImage.getWidth(); j++) {
				tempPixelColor =inImage.getRGB(j, i);
				red = (0xFF & tempPixelColor>>16);
				green = (0xFF & tempPixelColor>>8);
				blue = (0xFF & tempPixelColor);
				outImage.setRGB(j, i, (getFilteredPixel(red, RED)<<16)|getFilteredPixel(green, GREEN)<<8|getFilteredPixel(blue, BLUE));
			}
		}
		return outImage;
	}	
	
	/**
	 * @author Ahmed
	 *
	 */
	@Override 
	public int getFilteredPixel(int originalPixel, int colorComponent) {
		int stretchedColor =0 ;
		//find the right segment
		for (ColorRangeSegmentTransform segment : this.colorTransform[colorComponent]) {
			if (originalPixel >= segment.inputMin && originalPixel <= segment.inputMax){
				//calculate the new value of this colorcompnent 
				stretchedColor = ((originalPixel - segment.inputMin)*((segment.outMax-segment.outMin)/(segment.inputMax-segment.inputMin)) + segment.inputMax);
			}
		}
	
		//return new value
		return stretchedColor;
		//Amr & Ahmed
	}

//	int computeOutput (int originalColor, int r1, int s1, int r2, int s2, int max)
//	{
//		float result = 0;
//		if(0<= originalColor && originalColor <=r1)
//			result =(s1/r1)*originalColor;
//		else if(r1<originalColor && originalColor<=r2)
//			result =((s2-s1) / (r2 -r1)) * (originalColor-r1)+s1;
//		else if(r2<originalColor && originalColor<= max)
//			result =((max - s2)/ (max - r2))*(originalColor-r2) + s2;
//		return (int)result;
//	}

	/**
	 * @author Mohsen
	 *
	 */
	@Override 
	public Color getFilteredPixel(Color originalPixel) {
	
		int r = originalPixel.getRed();
		    r = getFilteredPixel(r,RED);
		
		int g = originalPixel.getGreen(); 
		    g = getFilteredPixel(g, GREEN);

		int b = originalPixel.getBlue();
		    b = getFilteredPixel(b, BLUE);
		    
		Color newColor = new Color (r, g, b);      
		
	return newColor;  
	}

}
